package net.sxnic.workflow.utils;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sxnic.comm.utils.CommUtils;
import net.sxnic.ugr.UgrConstant;
import net.sxnic.ugr.dept.Dept;
import net.sxnic.ugr.dept.DeptManager;
import net.sxnic.ugr.user.User;
import net.sxnic.ugr.user.UserManager;
import net.sxnic.ugr.utils.UgrManagerUtils;
import net.sxnic.workflow.node.NodeConfig;
import net.sxnic.workflow.task.util.TaskUtils;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 接收人处理工具类
 * 
 * @author 孙宇飞
 * 
 */
public class NextAssigneeUtils {

	private static Logger logger = LoggerFactory
			.getLogger(NextAssigneeUtils.class);

	/**
	 * 用户名之间分隔符
	 */
	public static final String NEXTASSIGNEES_SEPARATOR = ",";

	/**
	 * 节点之间的分隔符
	 */
	public static final String NODE_SEPARATOR = "&";

	/**
	 * 节点和用户名之间的分隔符
	 */
	public static final String NODE_NEXTASSIGNEES_SEPARATOR = ":";

	/**
	 * 在页面显示的时候，节点和用户之间的分隔符。如：批办-领导1,承办-处长2
	 */
	public static final String RECEIVES_SEPARATOR = "-";

	/**
	 * 传阅中领导的标志
	 */
	public static final String CHUANYUE_BIAOJI_LINGDAO = "a_";

	/**
	 * 传阅中处室的标记
	 */
	public static final String CHUANYUE_BIAOJI_CHUSHI = "b_";

	/**
	 * 把接收人列表处理为一个Map<节点名称,用户名数组>。
	 * <p>
	 * 如 承办:处长1,处长2 & 批办:领导1,领导2
	 * <p>
	 * 处理为：
	 * <p>
	 * key 承办 value 处长1,处长2
	 * <p>
	 * key 批办 value 领导1,领导2
	 * 
	 * @param nextAssignees
	 *            接收人列表
	 * @return
	 */
	public static Map<String, String[]> treatNextAssigneesToMap(
			String nextAssignees) {

		Map<String, String[]> map = new LinkedHashMap<String, String[]>();

		try {
			for (String node : StringUtils.split(nextAssignees.trim(),
					NODE_SEPARATOR)) {
				String nodeName = StringUtils.substringBefore(node,
						NODE_NEXTASSIGNEES_SEPARATOR).trim();
				String[] users = StringUtils.substringAfter(node,
						NODE_NEXTASSIGNEES_SEPARATOR).split(
						NEXTASSIGNEES_SEPARATOR);
				map.put(nodeName, users);
				logger.debug("map put | {} | {} | success!", nodeName, users);
			}
		} catch (Exception e) {
			logger.warn(
					"treatNextAssigneesToMap error ! NextAssignees is {} . error is {}",
					nextAssignees, e.toString());
			return null;
		}

		return map;
	}

	/**
	 * 把接收人列表处理为一个Map<用户名,节点名称>。由于有用户重名的可能，此方法谨慎使用！
	 * <p>
	 * 如 承办:处长1,处长2 & 批办:领导1,领导2
	 * <p>
	 * 处理为：
	 * <p>
	 * key 处长1 value 承办
	 * <p>
	 * key 处长2 value 承办
	 * <p>
	 * key 领导1 value 批办
	 * <p>
	 * key 领导2 value 批办
	 * 
	 * @param nextAssignees
	 *            接收人列表
	 * @return
	 */
	public static Map<String, String> treatNextAssigneesToMap1(
			String nextAssignees) {

		Map<String, String> map = new LinkedHashMap<String, String>();

		try {
			for (String node : StringUtils.split(nextAssignees.trim(),
					NODE_SEPARATOR)) {
				String nodeName = StringUtils.substringBefore(node,
						NODE_NEXTASSIGNEES_SEPARATOR).trim();
				String[] users = StringUtils.substringAfter(node,
						NODE_NEXTASSIGNEES_SEPARATOR).split(
						NEXTASSIGNEES_SEPARATOR);

				for (String user : users) {

					map.put(user.trim(), nodeName);
					logger.debug("map put | {} | {} | success!", user.trim(),
							nodeName);
				}
			}
		} catch (Exception e) {
			logger.warn(
					"treatNextAssigneesToMap error ! NextAssignees is {} . error is {}",
					nextAssignees, e.toString());
			return null;
		}

		return map;
	}

	/**
	 * 把一个map处理为String 。treatNextAssigneesToMap的逆向方法 传阅和处长特殊处理
	 * 
	 * @param map
	 * @return 接收人列表
	 */
	public static String treatMaptoNextAssignees(Map<String, String[]> map) {

		StringBuffer sb = new StringBuffer();
		String na = "";

		try {
			for (String nodeName : map.keySet()) {
				sb.append(nodeName);

				sb.append(NODE_NEXTASSIGNEES_SEPARATOR);
				if (map.get(nodeName)[0]
						.equals(NodeConfig.DEFAULTASSIGNEE_CHUSHI)) {
					sb.append(NodeConfig.DEFAULTASSIGNEE_CHUSHI);
				} else if (map.get(nodeName)[0]
						.equals(NodeConfig.DEFAULTASSIGNEE_CHUANYUE)) {
					sb.append(NodeConfig.DEFAULTASSIGNEE_CHUANYUE);
				} else {
					sb.append(StringUtils.join(map.get(nodeName),
							NEXTASSIGNEES_SEPARATOR));
				}
				sb.append(NODE_SEPARATOR);

			}

			na = StringUtils.removeEnd(sb.toString(), NODE_SEPARATOR);
		} catch (Exception e) {
			logger.warn(
					"treatMaptoNextAssignees error ! map is {} . error is {}",
					map, e.toString());
			return null;
		}

		return na;
	}

	/**
	 * 把一个map处理为String 。treatNextAssigneesToMap1的逆向方法
	 * 
	 * @param map
	 * @return 接收人列表
	 */
	public static String treatMaptoNextAssignees1(Map<String, String[]> map) {

		StringBuffer sb = new StringBuffer();
		String na = "";

		try {
			for (String nodeName : map.keySet()) {
				sb.append(nodeName);
				sb.append(NODE_NEXTASSIGNEES_SEPARATOR);
				sb.append(StringUtils.join(map.get(nodeName),
						NEXTASSIGNEES_SEPARATOR));
				sb.append(NODE_SEPARATOR);
			}

			na = StringUtils.removeEnd(sb.toString(), NODE_SEPARATOR);
		} catch (Exception e) {
			logger.warn(
					"treatMaptoNextAssignees1 error ! map is {} . error is {}",
					map, e.toString());
			return null;
		}

		return na;
	}

	/**
	 * 把已选的接收人列表中的用户名，替换为用户全名。即userName-->fullName
	 * <p>
	 * 如 承办:处长1userName,处长2userName & 批办:领导1userName,领导2userName
	 * <p>
	 * 处理为：承办:处长1fullName,处长2fullName & 批办:领导1fullName,领导2fullName
	 * 
	 * @param nextAssignees
	 * @return
	 */
	public static String treatNextAssigneetoName(String nextAssignees) {

		Map<String, String[]> map = new LinkedHashMap<String, String[]>();

		try {
			for (String node : StringUtils.split(nextAssignees.trim(),
					NODE_SEPARATOR)) {
				String nodeName = StringUtils.substringBefore(node,
						NODE_NEXTASSIGNEES_SEPARATOR).trim();
				String[] users = StringUtils.substringAfter(node,
						NODE_NEXTASSIGNEES_SEPARATOR).split(
						NEXTASSIGNEES_SEPARATOR);

				String[] tmp = new String[users.length];
				int i = 0;
				for (String u : users) {
					tmp[i] = UgrConstant.USER_MAP.get(u);
					i++;
				}
				map.put(nodeName, tmp);

				logger.debug("map put | {} | {} | success!", nodeName, tmp);
			}
			return treatMaptoNextAssignees(map);
		} catch (Exception e) {
			logger.warn(
					"treatNextAssigneetoName error ! NextAssigneeNames is {} . error is {}",
					nextAssignees, e.toString());
			return null;
		}

	}

	/**
	 * 根据下个节点的所有用户名，创建html代码 承办和传阅特殊处理 如果只有一个接收人，则默认为选择状态
	 * 
	 * @param receivers
	 * @return
	 */
	public static String createReceiversHtml(String receivers) {
		UserManager userManager = UgrManagerUtils.getUserManager();
		DeptManager deptManager = UgrManagerUtils.getDeptManager();
		Map<String, String[]> map = treatNextAssigneesToMap(receivers);

		StringBuffer sb = new StringBuffer();
		String html = "";
		boolean isOne = false;

		// 验证接受人的个数，如果是一个则默认为选中，多个则不选。
		if (map != null) {
			String[] temp = StringUtils.split(receivers, NODE_SEPARATOR);
			int i = 0;
			for (String str : temp) {
				String[] tmp = StringUtils.split(str, NEXTASSIGNEES_SEPARATOR);
				i = i + tmp.length;
			}

			if (i == 1) {
				isOne = true;
			}
		}

		// TODO 特殊节点的设置，如承办和传阅
		try {
			for (String nodeName : map.keySet()) {
				sb.append("<div style='clear:both;padding-top:15px;'><span class='itemname'>");
				sb.append(nodeName);
				sb.append(NODE_NEXTASSIGNEES_SEPARATOR);
				sb.append("</span></div>");

				sb.append("<ul class='row' style='clear:both'>");
				for (String u : map.get(nodeName)) {
					// 处室和传阅特殊处理
					if (u.equals(NodeConfig.DEFAULTASSIGNEE_CHUSHI)) {
						// 所有职能处室，除厅领导之外
						List<Dept> list = deptManager.findPureFunctionDepart();
						for (Dept g : list) {
							// 根据部门编码查找处长user
							User uuu = userManager.findGroupLeaderByDept(g
									.getCode());
							if (uuu == null) {
								continue;
							}
							sb.append("<li><input width='50px' type='checkbox' name='nextAssignee' value='"
									+ nodeName
									+ RECEIVES_SEPARATOR
									+ uuu.getUsername() // 处长username
									+ "'/>" + g.getName() // 处室名
									+ "</li>");
						}

					} else if (u.equals(NodeConfig.DEFAULTASSIGNEE_CHUANYUE)) {

					} else {
						if (isOne) {
							// 一般性处理
							sb.append("<li><input width='50px' type='checkbox' name='nextAssignee' value='"
									+ nodeName
									+ RECEIVES_SEPARATOR
									+ u
									+ "' checked='true'/>"
									+ UgrConstant.USER_MAP.get(u) + "</li>");
						} else {
							// 一般性处理
							sb.append("<li><input width='50px' type='checkbox' name='nextAssignee' value='"
									+ nodeName
									+ RECEIVES_SEPARATOR
									+ u
									+ "'/>"
									+ UgrConstant.USER_MAP.get(u) + "</li>");
						}
					}

				}
				sb.append("</ul>");
			}

			html = sb.toString();
		} catch (Exception e) {
			logger.warn("createReceiversHtml error ! map is {} . error is {}",
					map, sb.toString());
			return sb.toString();
		}

		return html;
	}

	/**
	 * 在view的时候，显示已选接收人html代码
	 * 
	 * @param nextAssigneeNames
	 * @return
	 */
	public static String createSelectReceiversHtml(String nextAssigneeNames) {

		if (StringUtils.isBlank(nextAssigneeNames)) {
			return "";
		}

		return nextAssigneeNames.replace("&", "<br>");
	}

	/**
	 * 从页面上得到的已选接收人应该是一个数组，然后在保存之前，对其格式化。 注意：不能有空格。数组在使用前先剔除空格。
	 * 
	 * @param selectedNextAssignees
	 *            如：批办-领导1,批办-领导3,承办－处长1,承办-处长2
	 * @return 如 承办:处长1,处长2&批办:领导1,领导3
	 */
	public static String formatNextAssignees(String[] selectedNextAssignees) {

		if (selectedNextAssignees == null || selectedNextAssignees.length == 0) {
			logger.info(
					" formatNextAssignees method's parameter {} is null or length is 0",
					selectedNextAssignees);
			return "";
		}

		Set<String> nextNodeNames = new LinkedHashSet<String>();

		for (String na : selectedNextAssignees) {
			if (!nextNodeNames.contains(na.trim())) {
				nextNodeNames.add(StringUtils.substringBefore(na.trim(),
						RECEIVES_SEPARATOR).trim());
			}
		}

		StringBuffer sb1 = new StringBuffer();

		for (String nodeName : nextNodeNames) {
			StringBuffer sb = new StringBuffer();
			sb.append(nodeName + NODE_NEXTASSIGNEES_SEPARATOR);
			for (String na : selectedNextAssignees) {
				if (nodeName.equals(StringUtils.substringBefore(na.trim(),
						RECEIVES_SEPARATOR))) {
					sb.append(StringUtils
							.substringAfter(na, RECEIVES_SEPARATOR)
							+ NEXTASSIGNEES_SEPARATOR);
				}
			}

			String temp = sb.toString();
			temp = StringUtils.removeEnd(temp, NEXTASSIGNEES_SEPARATOR);
			sb1.append(temp + NODE_SEPARATOR);
		}

		String temp = sb1.toString();

		return StringUtils.removeEnd(temp, NODE_SEPARATOR);
	}

	/**
	 * 处理会签、传阅人员的格式。
	 * 
	 * @param nextAssignee格式
	 *            会签-user1,会签-user2,会签-user3,会签-user4
	 * @param node
	 *            会签
	 * @return 会签:user1,user2,user3,user4
	 */
	public static String findSepcailAssignee(String nextAssignee, String node) {

		if (StringUtils.isBlank(nextAssignee) || StringUtils.isBlank(node)) {
			logger.info(
					" findSepcailAssignee method's parameter : {} or {} is null",
					nextAssignee, node);
			return "";
		}

		String temp = "";
		String[] assignees = StringUtils.split(nextAssignee,
				TaskUtils.NEXTASSIGNEES_SEPARATOR);

		for (String a : assignees) {
			if (a.trim().startsWith(node)) {
				temp = temp
						+ StringUtils.substringAfterLast(a.trim(),
								TaskUtils.RECEIVES_SEPARATOR) + ",";
			}
		}

		return node + TaskUtils.NODE_NEXTASSIGNEES_SEPARATOR
				+ StringUtils.removeEnd(temp, ",");
	}

	/**
	 * 对map排序
	 * <p>
	 * 比如一个map 承办:处长2userName,处长1userName & 批办:领导2userName,领导1userName
	 * <p>
	 * 处理结果 批办:领导1userName,领导2userName & 承办:处长1userName,处长2userName
	 * <p>
	 * 思路：按每个节点所有人员的平均排名，排名靠前则在前面。
	 * <p>
	 * 
	 * @param fmap
	 * @return
	 */
	public static Map<String, String[]> sortNodes(Map<String, String[]> fmap) {

		Map<String, String[]> map = new LinkedHashMap<String, String[]>();

		if (fmap == null) {
			return map;
		}

		// user排序
		if (fmap.size() == 1) {
			return fmap;
		}

		UserManager userManager = UgrManagerUtils.getUserManager();

		// node排序
		String[] nodes = CommUtils.SettoArray(fmap.keySet());

		int length = nodes.length;

		String[][] nodeNum = new String[length][2];

		int i = 0;
		for (String node : nodes) {
			nodeNum[i][1] = nodes[i];

			long all = 0;
			int num = 0;
			for (String u : fmap.get(node)) {
				all += Long.parseLong(String.valueOf(userManager
						.getUserByUsername(u).getUserOrder()));
				num += 1;
			}

			nodeNum[i][0] = String.valueOf(Math.floor(all / num));

			i++;
		}

		String temp = "";
		// 排序
		for (i = 1; i < length; i++) {
			for (int j = 0; j < length - i; j++) {

				if (Float.parseFloat(nodeNum[j][0]) > Float
						.parseFloat(nodeNum[j + 1][0])) {

					temp = nodeNum[j][0];
					nodeNum[j][0] = nodeNum[j + 1][0];
					nodeNum[j + 1][0] = temp;

					temp = nodeNum[j][1];
					nodeNum[j][1] = nodeNum[j + 1][1];
					nodeNum[j + 1][1] = temp;
				}
			}
		}

		for (i = 0; i < length; i++) {
			map.put(nodeNum[i][1], fmap.get(nodeNum[i][1]));
		}

		return map;
	}

	/**
	 * 对一个users序列按其排名排序
	 * 
	 * @param users
	 * @return
	 */
	public static String sortUsers(String users) {

		if (StringUtils.isBlank(users)) {
			return "";
		}

		UserManager userManager = UgrManagerUtils.getUserManager();

		String[] us = StringUtils.split(users, ",");
		String[][] uss = new String[us.length][2];

		int i = 0;
		for (String u : us) {
			uss[i][1] = us[i];
			uss[i][0] = String.valueOf(userManager.getUserByUsername(
					(uss[i][1])).getUserOrder());
		}

		return null;
	}

	public static void swap(String str1, String str2) {
		String temp = str1;

		str1 = str2;
		str2 = temp;
	}

}
